package com.example.demo.Controller.Opus_Like;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.Entity.Opus.Opus;
import com.example.demo.Entity.UserInfo.Userinfo;
import com.example.demo.ServiceImpl.Opus.OpusServiceImpl;
import com.example.demo.ServiceImpl.Opus_Like.OpusLikeServiceImpl;
import com.example.demo.Entity.Opus_Like.OpusLike;
import com.example.demo.ServiceImpl.UserInfo.UserinfoServiceImpl;
import com.example.demo.Utils.JWTUtils.JWTUtils;
import com.example.demo.Utils.RedisUtils.RedisUtil;
import com.example.demo.Utils.Result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/opusLike")
@Tag(name = "OpusLikeController", description = "OpusLikeController 相关接口")
public class OpusLikeController {

    @Resource
    private OpusLikeServiceImpl opusLikeService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private UserinfoServiceImpl userinfoService;

    @Resource
    private OpusServiceImpl opusService;

    @Resource
    private RedisUtil redisUtil;

    @PostMapping
    @Operation(summary = "保存或更新 OpusLike 信息", description = "根据传入的 OpusLike 对象保存或更新信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "保存或更新成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean save(@RequestBody OpusLike opusLike, HttpServletRequest request) {
// 保存或更新数据后，删除相关缓存
        redisTemplate.delete("opusLike:all");
        redisUtil.deleteKeysStartingWith("opusLike");
        if (opusLike.getLikeUserId() == null) {
            String token = request.getHeader("Authorization");
            Integer userId = Integer.parseInt(JWTUtils.getUserIDFromToken(token));
            opusLike.setLikeUserId(userId);
            opusLike.setCreateTime(new Date());
        }
        return opusLikeService.saveOrUpdate(opusLike);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "根据 ID 删除 OpusLike 信息", description = "根据传入的 ID 删除对应的 OpusLike 信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "删除成功", content = @Content(schema = @Schema(implementation = Boolean.class)))
    })
    public Boolean delete(@PathVariable(value = "id") Integer id) {
// 删除数据后，删除相关缓存
        redisTemplate.delete("opusLike:all");
        redisTemplate.delete("opusLike:id:" + id);
        redisUtil.deleteKeysStartingWith("opusLike");
        return opusLikeService.removeById(id);
    }

    @GetMapping
    @Operation(summary = "获取所有 OpusLike 信息", description = "获取所有 OpusLike 的列表信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    public R findAll() {
        String key = "opusLike:all";
        List<OpusLike> opusLikeList = (List<OpusLike>) redisTemplate.opsForValue().get(key);
        if (opusLikeList == null) {
            opusLikeList = opusLikeService.list();
            redisTemplate.opsForValue().set(key, opusLikeList, 60, TimeUnit.MINUTES);
        }
        return R.ok().put("opusLikeList", opusLikeList);
    }

    @GetMapping("/{id}")
    @Operation(summary = "根据 ID 获取 OpusLike 信息", description = "根据传入的 ID 获取对应的 OpusLike 信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    public R findOne(@PathVariable(value = "id") Integer id) {
        String key = "opusLike:id:" + id;
        OpusLike opusLike = (OpusLike) redisTemplate.opsForValue().get(key);
        if (opusLike == null) {
            opusLike = opusLikeService.getById(id);
            if (opusLike != null) {
                redisTemplate.opsForValue().set(key, opusLike, 60, TimeUnit.MINUTES);
            }
        }
        return R.ok().put("opusLike", opusLike);
    }

    @GetMapping("/page")
    @Operation(summary = "分页获取 OpusLike 信息", description = "根据传入的页码和每页数量分页获取 OpusLike 信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功", content = @Content(schema = @Schema(implementation = R.class)))
    })
    @Parameter(name = "pageNum", in = ParameterIn.QUERY, description = "页码", required = true)
    @Parameter(name = "pageSize", in = ParameterIn.QUERY, description = "每页数量", required = true)
    @Parameter(name = "keyword", in = ParameterIn.QUERY, description = "搜索关键字")
    public R findPage(@RequestParam(value = "pageNum") Integer pageNum,
                      @RequestParam(value = "pageSize") Integer pageSize,
                      @RequestParam(value = "keyword", required = false)String keyword){
        String key = "opusLike:page:" + pageNum + ":" + pageSize+":keyword:" + keyword;
        Page<OpusLike> opusLikePage = (Page<OpusLike>) redisTemplate.opsForValue().get(key);
        if (opusLikePage == null) {
            LambdaQueryWrapper<OpusLike> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.orderByDesc(OpusLike::getLikeId);
            if (keyword != null && !keyword.isEmpty()) {
                LambdaQueryWrapper<Userinfo>userinfoQueryWrapper = new LambdaQueryWrapper<>();
                userinfoQueryWrapper.eq(Userinfo::getNickname, keyword);
                List<Userinfo> userinfoList = userinfoService.list(userinfoQueryWrapper);
                List<Integer> userIds = userinfoList.stream().map(Userinfo::getUserId).toList();
                if (!userIds.isEmpty()) {
                    queryWrapper.or().in(OpusLike::getLikeUserId, userIds);
                }
                LambdaQueryWrapper<Opus>opusLambdaQueryWrapper = new LambdaQueryWrapper<>();
                opusLambdaQueryWrapper.eq(Opus::getOpusTitle, keyword);
                List<Opus> opusList = opusService.list(opusLambdaQueryWrapper);
                List<Integer> opusIds = opusList.stream().map(Opus::getOpusId).toList();
                if (!opusIds.isEmpty()) {
                    queryWrapper.or().in(OpusLike::getOpusId, opusIds);
                }
            }
            opusLikePage = opusLikeService.page(new Page<>(pageNum, pageSize),queryWrapper);
            redisTemplate.opsForValue().set(key, opusLikePage, 60, TimeUnit.MINUTES);
        }
        List<String>OpusNameList=new ArrayList<>();
        List<String>UserNameList=new ArrayList<>();
        for (OpusLike opusLike:opusLikePage.getRecords()){
            Integer opusId=opusLike.getOpusId();
            Integer userId=opusLike.getLikeUserId();
            Opus opus=opusService.getById(opusId);
            LambdaQueryWrapper<Userinfo>userinfoQueryWrapper = new LambdaQueryWrapper<>();
            userinfoQueryWrapper.eq(Userinfo::getUserId, opusLike.getLikeUserId());
            Userinfo userinfo=userinfoService.getOne(userinfoQueryWrapper);
            if(userinfo!=null){
                UserNameList.add(userinfo.getNickname());
            }else {
                UserNameList.add("");
            }
            if(opus!=null){
                OpusNameList.add(opus.getOpusTitle());
            }else {
                OpusNameList.add("");
            }
        }
        return R.ok().put("opusLikePage", opusLikePage).put("OpusNameList",OpusNameList).put("UserNameList",UserNameList);
    }
}